from django.shortcuts import render

# Create your views here.
import uuid
# from .TokenAuthtication import TokenAuthtication
from rest_framework.response import Response
from django.core.paginator import Paginator
from rest_framework.views import APIView
from django.views import View
from django.http import HttpResponse, JsonResponse
from djangoProject import settings
from .Serializer import *
from .models import *
import datetime
import jwt
import os
import hashlib

# 前台返回格式
ret = {
    "data": {},
    "meta": {
        "status": 200,
        "message": "注册成功"
    }
}


# 人头识别接口
class imgApiview(View):
    def get(self, request):
        return JsonResponse(data={'code': 200, 'message': '方法测试'})

    # 图片上传接口通过 request.data 可以接收到前端发来的
    def post(self, request):
        response = {}
        dataduixiang = request.POST.get('data', '')
        file = request.FILES.get('file')
        # try:
        # 构造图片保存路径 路径为<USER_AVATAR_ROOT + 文件名>
        # USER_AVATAR_ROOT刚刚在settings.py中规定过，需要导入进来
        filename = "tx--sb" + file.name
        file_path = os.path.join(settings.MEDIA_ROOT, filename)
        # 保存图片
        print(dataduixiang, file)
        with open(file_path, 'wb+') as f:
            f.write(file.read())
            f.close()

        detect(file_path, filename)

        response['file'] = filename  # 返回新的文件名
        response['code'] = 0
        response['message'] = "图片上传成功！"
        return JsonResponse(data={'code': 200, 'message': '上传成功', 'data': response})


import cv2


def detect(file_path, filename):
    # haarcascade_frontalface_default.xml 此为opencv内置人脸识别模型
    face_cascade = cv2.CascadeClassifier(
        "D:\\workspace\\pycharmworkspace\\djangoProject\\bookapp\\face_recognition_model.xml")

    # 读取图像
    im = cv2.imread(file_path)
    # 转为灰度图
    im_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)

    # 检测结果返回人脸矩形数组
    faces = face_cascade.detectMultiScale(im_gray, 1.3, 5)

    # 遍历每张脸，画一个矩形
    for (x, y, w, h) in faces:
        im = cv2.rectangle(im, (x, y), (x + w, y + h), (255, 0, 0), 2)

    # 保存标记好的输出图像
    cv2.imwrite("D:\\workspace\\pycharmworkspace\\djangoProject\\upimg2\\" + filename, im)


# 图片上传接口
class img_uploadApiview(View):
    def get(self, request):
        return JsonResponse(data={'code': 200, 'message': '方法测试'})

    # 图片上传接口通过 request.data 可以接收到前端发来的
    def post(self, request):
        response = {}
        dataduixiang = request.POST.get('data', '')
        file = request.FILES.get('file')
        # try:
        # 构造图片保存路径 路径为<USER_AVATAR_ROOT + 文件名>
        # USER_AVATAR_ROOT刚刚在settings.py中规定过，需要导入进来
        filename = str(uuid.uuid4()) + "_" + file.name
        file_path = os.path.join(settings.MEDIA_ROOT, filename)
        # 保存图片
        # print(dataduixiang, file)
        with open(file_path, 'wb+') as f:
            f.write(file.read())
            f.close()
        response['file'] = filename  # 返回新的文件名
        response['code'] = 0
        response['message'] = "图片上传成功！"
        return JsonResponse(data={'code': 200, 'message': '上传成功', 'data': response})


# 密码加密 64位
def f_sha256(arg):
    sha256_pwd = hashlib.sha256()
    sha256_pwd.update(arg.encode("utf8"))
    return sha256_pwd.hexdigest()


# 用户名 admin 密码 admin123 管理员
# 用户名 test 密码 test123456 普通用户

# 用户登录
class LoginView(APIView):
    def post(self, request):
        ret = {
            "data": {},
            "success": False
        }
        try:
            username = request.data["username"]
            # 加密
            password = f_sha256(request.data["password"])
            user = Guanli.objects.filter(username=username, password=password)
            print(username, password, user)
            if user.count == 0:
                ret["success"] = False
                return Response(ret)
            elif user and user.first().password:
                dict = {
                    "exp": datetime.datetime.now() + datetime.timedelta(days=1),  # 过期时间
                    "iat": datetime.datetime.now(),  # 开始时间
                    "id": user.first().id,
                    "username": user.first().username,
                }
                token = jwt.encode(dict, settings.SECRET_KEY, algorithm="HS256")
                ret["data"]["accessToken"] = token
                ret["data"]["username"] = user.first().username
                ret["data"]["nickname"] = user.first().nickname
                # ret["data"]["user_id"] = user.first().id
                # 这里需要根据数据库判断是不是管理员
                if user.first().role == 1:
                    ret["data"]["roles"] = ['admin']
                    ret["data"]["refreshToken"] = "eyJhbGciOiJIUzUxMiJ9.adminRefresh"
                else:
                    ret["data"]["roles"] = ['common']
                    ret["data"]["refreshToken"] = "eyJhbGciOiJIUzUxMiJ9.commonRefresh"

                ret["data"][
                    "avatar"] = "https://upload-bbs.mihoyo.com/upload/2022/09/12/103362688/c6304a690ae3c9298dc53794bc49ba22_9060620435758831259.png?x-oss-process=image/resize,s_600/quality,q_80/auto-orient,0/interlace,1/format,png"
                ret["data"]["expires"] = "2030/10/30 00:00:00"
                ret["success"] = True
                print(ret, type(ret))
                return Response(ret)
            else:
                ret["success"] = False
                return Response(ret)
        except Exception as error:
            print(error)
            ret["success"] = False
            return Response(ret)


# 出版社管理
class Cbsview(APIView):

    def get(self, request):
        # 获取数据集（出版社模型对象）
        publish_data = Publish.objects.all()
        pageNum = request.GET.get('currentPage', '')
        pageSize = request.GET.get('pageSize', 10)
        # 过滤
        search_nick_term = request.GET.get('keyword', '')
        if search_nick_term:
            search_nick_term = search_nick_term.strip()
            publish_data = publish_data.filter(name__icontains=search_nick_term)
        # 自定义分页 过滤后再次分页
        paginator = Paginator(publish_data, pageSize)
        page_obj = paginator.get_page(pageNum)
        # 拿到分页对象
        page_obj_dq = page_obj.object_list
        # 拿到总数
        page_obj_zs = paginator.count
        # 实例化序列化器，得到序列化器对象
        # 分页对象进行序列化
        ser = PublishSerializer(instance=page_obj_dq, many=True)
        # 调用序列化器对象的data属性方法获取转换后的数据
        data = ser.data

        # 响应数据
        return Response(data={'code': 200, 'total': page_obj_zs, 'data': data})

    def post(self, request):
        print(request.data)
        # 反序列化数据
        publish = PublishSerializer(data=request.data)
        # 校验不通过
        if not publish.is_valid():
            # 返回错误信息
            return Response(data={'code': 500, 'data': publish.errors})
        # 校验通过，保存数据
        publish.save()
        # 响应数据
        return Response(data={'code': 200, 'message': '增加成功', 'data': publish.data})


class Cbsdetailview(APIView):
    # authentication_classes = [TokenAuthtication]

    def get(self, request, pk):
        publish = Publish.objects.get(pk=pk)
        ser = PublishSerializer(instance=publish)
        return Response(ser.data)

    # 修改一个学生的信息
    def put(self, request, pk):
        print(request.data)
        instance = Publish.objects.get(pk=pk)
        ser = PublishSerializer(instance=instance, data=request.data)
        if not ser.is_valid():
            return Response(data={'code': 500, 'message': ser.errors})
        ser.save()
        return Response(data={'code': 200, 'message': '修改成功', 'data': ser.data})

    # 删除一个学生的信息
    def delete(self, request, pk):
        Publish.objects.get(pk=pk).delete()
        return Response(data={'code': 200, 'message': '删除成功'})


# 作者管理
class Zzview(APIView):
    # 单个禁用 token 验证
    # authentication_classes = [TokenAuthtication]

    def get(self, request):
        # 获取数据集（学生模型对象）
        author_data = Author.objects.all()
        pageNum = request.GET.get('currentPage', '')
        pageSize = request.GET.get('pageSize', 10)
        # 过滤
        search_nick_term = request.GET.get('keyword', '')
        if search_nick_term:
            search_nick_term = search_nick_term.strip()
            author_data = author_data.filter(name__icontains=search_nick_term)
        # 自定义分页 过滤后再次分页
        paginator = Paginator(author_data, pageSize)
        page_obj = paginator.get_page(pageNum)
        # 拿到分页对象
        page_obj_dq = page_obj.object_list
        # 拿到总数
        page_obj_zs = paginator.count
        # 实例化序列化器，得到序列化器对象
        # 分页对象进行序列化
        ser = AuthorSerializer(instance=page_obj_dq, many=True)
        # 调用序列化器对象的data属性方法获取转换后的数据
        data = ser.data

        # 响应数据
        return Response(data={'code': 200, 'total': page_obj_zs, 'data': data})

    def post(self, request):
        print(request.data)
        # 反序列化数据
        author = AuthorSerializer(data=request.data)
        # 校验不通过
        if not author.is_valid():
            # 返回错误信息
            return Response(data={'code': 500, 'data': author.errors})
        # 校验通过，保存数据
        author.save()
        # 响应数据
        return Response(data={'code': 200, 'message': '增加成功', 'data': author.data})


class Zzdetailview(APIView):
    # authentication_classes = [TokenAuthtication]

    def get(self, request, pk):
        author = Author.objects.get(pk=pk)
        ser = AuthorSerializer(instance=author)
        return Response(ser.data)

    # 修改一个作者的信息
    def put(self, request, pk):
        print(request.data)
        instance = Author.objects.get(pk=pk)
        ser = AuthorSerializer(instance=instance, data=request.data)
        if not ser.is_valid():
            return Response(data={'code': 500, 'message': ser.errors})
        ser.save()
        return Response(data={'code': 200, 'message': '修改成功', 'data': ser.data})

    # 删除一个作者的信息
    def delete(self, request, pk):
        Author.objects.get(pk=pk).delete()
        return Response(data={'code': 200, 'message': '删除成功'})


# 图书管理
class TSview(APIView):
    # 单个禁用 token 验证
    # authentication_classes = [TokenAuthtication]

    def get(self, request):
        # 获取数据集（图书模型对象）
        book_data = Book.objects.all()
        print(request.POST)
        pageNum = request.GET.get('currentPage', '')  # 第几条数据
        pageSize = request.GET.get('pageSize', 10)  # 每一页展示几条
        # 过滤
        search_nick_term = request.GET.get('keyword', '')
        if search_nick_term:
            search_nick_term = search_nick_term.strip()
            book_data = book_data.filter(title__icontains=search_nick_term)
        # 自定义分页 过滤后再次分页
        print(book_data)
        paginator = Paginator(book_data, pageSize)
        page_obj = paginator.get_page(pageNum)
        # 拿到分页对象
        page_obj_dq = page_obj.object_list
        # 拿到总数
        page_obj_zs = paginator.count
        # 实例化序列化器，得到序列化器对象
        # 分页对象进行序列化
        ser = BookInfoModelSerializermodel(instance=page_obj_dq, many=True)
        # 调用序列化器对象的data属性方法获取转换后的数据
        data = ser.data

        # 响应数据
        return Response(data={'code': 200, 'total': page_obj_zs, 'data': data})

    def post(self, request):
        print(request.data)
        # 反序列化数据
        book = BookInfoModelSerializermodel(data=request.data)
        # 校验不通过
        if not book.is_valid():
            # 返回错误信息
            return Response(data={'code': 500, 'data': book.errors})
        # 校验通过，保存数据
        book.save()
        # 响应数据
        return Response(data={'code': 200, 'message': '增加成功', 'data': book.data})


class Tsdetailview(APIView):
    # authentication_classes = [TokenAuthtication]

    def get(self, request, pk):
        book = Book.objects.get(pk=pk)
        ser = BookInfoModelSerializermodel(instance=book)
        return Response(ser.data)

    # 修改图书信息
    def put(self, request, pk):
        print(request.data)
        instance = Book.objects.get(pk=pk)
        ser = BookInfoModelSerializermodel(instance=instance, data=request.data)
        if not ser.is_valid():
            return Response(data={'code': 500, 'message': ser.errors})
        ser.save()
        return Response(data={'code': 200, 'message': '修改成功', 'data': ser.data})

    # 删除图书信息
    def delete(self, request, pk):
        Book.objects.get(pk=pk).delete()
        return Response(data={'code': 200, 'message': '删除成功'})


class DataView(APIView):
    def get(self, request):
        try:
            data = [
                {"axis": "图书数量", "series": Book.objects.count()},
                {"axis": "作者数量", "series": Author.objects.count()},
                {"axis": "出版社数量", "series": Publish.objects.count()},
            ]
            # 响应数据
            return Response(data={'code': 200, 'data': data})
        except Exception as e:
            # 处理数据库错误等异常情况
            return Response(data={'code': 500, 'error': str(e)})
